package ru.arriah.servicedesk.web.dispatcher.action;

import java.io.IOException;
import java.text.DateFormat;
import java.util.Collection;
import java.util.Locale;
import java.util.regex.Pattern;

import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ru.arriah.common.web.action.ActionMapping;
import ru.arriah.common.web.action.DumbAction;
import ru.arriah.servicedesk.bean.ClientBean;
import ru.arriah.servicedesk.bean.ClientTypeBean;
import ru.arriah.servicedesk.bean.DepartmentBean;
import ru.arriah.servicedesk.bean.MailTemplateBean;
import ru.arriah.servicedesk.bean.OrganizationBean;
import ru.arriah.servicedesk.bean.error.ClientFormErrorBean;
import ru.arriah.servicedesk.ejb.ClientManagerLocalHome;
import ru.arriah.servicedesk.ejb.ClientManagerLocalObject;
import ru.arriah.servicedesk.ejb.OrganizationManagerLocalHome;
import ru.arriah.servicedesk.ejb.OrganizationManagerLocalObject;
import ru.arriah.servicedesk.ejb.UtilityManagerLocalHome;
import ru.arriah.servicedesk.ejb.UtilityManagerLocalObject;
import ru.arriah.servicedesk.help.MailSender;
import ru.arriah.servicedesk.help.Utils;
import ru.arriah.servicedesk.web.commonaction.exception.InternalException;

public class ProcessClientFormAction extends DumbAction {
   
   protected ClientManagerLocalHome clientManagerHome;
   protected ClientFormErrorBean clientFormErrorBean;
   protected OrganizationManagerLocalHome organizationManagerHome;
   protected UtilityManagerLocalHome utilityManagerHome;
   
   public ProcessClientFormAction() throws NamingException {
      super();

      clientManagerHome =
         Utils.getClientManagerHomeInterface(); 
      
      organizationManagerHome =
        Utils.getOrganizationManagerHomeInterface();
      
      utilityManagerHome = 
         Utils.getUtilityManagerHomeInterface();            
   }
   
   
   private boolean isValid(
     ClientBean clientBean,
     ClientManagerLocalObject clientManager
   ) throws InternalException {
     
      boolean valid = true;
      
     try {
     clientFormErrorBean = new ClientFormErrorBean();
     
     Pattern emailPattern = Pattern.compile(
       config.getProperty("REGEXP.EMAIL"),
       Pattern.CASE_INSENSITIVE
     );     
     
     if (clientBean.getOrganizationId() == 0) {
       clientFormErrorBean.setOrganization(
         config.getProperty("ERROR.CLIENTFORM.ORGANIZATION")
       );
       valid = false;
     }
     
     if (clientBean.getDepartmentId() == 0) {
       clientFormErrorBean.setDepartment(
         config.getProperty("ERROR.CLIENTFORM.DEPARTMENT")
       );
       valid = false;
     }
     
     if (clientBean.getClientTypeId() == 0) {
       clientFormErrorBean.setType(
         config.getProperty("ERROR.CLIENTFORM.TYPE")
       );
       valid = false;
     }
     
     if (clientBean.getLogin().equals("") || clientBean.getLogin() == null) {
       clientFormErrorBean.setLogin(
         config.getProperty("ERROR.CLIENTFORM.LOGIN")
       );
       valid = false;
     } else {
       ClientBean existClient = 
         clientManager.selectClientByLogin(clientBean.getLogin());
       if (existClient != null) {
         if (existClient.getId() != clientBean.getId()) {
           clientFormErrorBean.setLogin(
             config.getProperty("ERROR.CLIENTFORM.LOGIN_EXIST")
           );
           valid = false;
         }
       }
     }
     
//     if (clientBean.getPassword().equals("") || clientBean.getPassword() == null) {
//       clientFormErrorBean.setPassword(
//         config.getProperty("ERROR.CLIENTFORM.PASSWORD")
//       );
//       valid = false;
//     }
//     
//     if (clientBean.getRePassword().equals("") || clientBean.getRePassword() == null) {
//       clientFormErrorBean.setRePassword(
//         config.getProperty("ERROR.CLIENTFORM.REPASSWORD")
//       );
//       valid = false;
//     } else if (!clientBean.getRePassword().equals(clientBean.getPassword())) {
//       clientFormErrorBean.setRePassword(
//         config.getProperty("ERROR.CLIENTFORM.REPASSWORD_INVALID")
//       );
//       valid = false;
//     }
     
     if (clientBean.getFirstName().equals("") || clientBean.getFirstName() == null) {
       clientFormErrorBean.setFirstName(
         config.getProperty("ERROR.CLIENTFORM.FIRSTNAME")
       );
       valid = false;
     }
     
     if (clientBean.getLastName().equals("") || clientBean.getLastName() == null) {
       clientFormErrorBean.setLastName(
         config.getProperty("ERROR.CLIENTFORM.LASTNAME")
       );
       valid = false;
     }
     
     if (clientBean.getMiddleName().equals("") || clientBean.getMiddleName() == null) {
       clientFormErrorBean.setMiddleName(
         config.getProperty("ERROR.CLIENTFORM.MIDDLENAME")
       );
       valid = false;
     }
     
     if (clientBean.getEmail1() == null || clientBean.getEmail1().equals("")) {
       clientFormErrorBean.setEmail1(
         config.getProperty("ERROR.CLIENTFORM.EMAIL_EMPTY")
       );
       valid = false;
     } else if (!emailPattern.matcher(clientBean.getEmail1()).matches()) {
       clientFormErrorBean.setEmail1(
         config.getProperty("ERROR.CLIENTFORM.EMAIL_INVALID")
       );
       valid = false;
     }
     
     if (!emailPattern.matcher(clientBean.getEmail2()).matches()) {
       clientFormErrorBean.setEmail2(
         config.getProperty("ERROR.CLIENTFORM.EMAIL_INVALID")
       );
       valid = false;
     }
     
     if (!emailPattern.matcher(clientBean.getEmail3()).matches()) {
       clientFormErrorBean.setEmail3(
         config.getProperty("ERROR.CLIENTFORM.EMAIL_INVALID")
       );
       valid = false;
     }
          
     return valid;
     } catch (Exception e) {
       handleException(e, "isValid");
       throw new InternalException("ErrorMessage.internal");
     }
   }
   
   
   /**
    * Send mail to client with login and password
    * @param clientBean
    */
   public void sendMail(ClientBean clientBean) {
     try {      
       UtilityManagerLocalObject utilityManager = 
         utilityManagerHome.create();
       
       MailSender mailSender = new MailSender();           
       
       mailSender.setSmtpPort(config.getProperty("SMTP_PORT"));
       mailSender.setHostName(config.getProperty("SMTP_HOST_NAME"));
       mailSender.setFrom(config.getProperty("FROM"));
       mailSender.setCharset("UTF-8");
       
       mailSender.setAuthentication(
         config.getProperty("LOGIN"), 
         config.getProperty("PASSWORD")
       );
       
       MailTemplateBean mailTemplate = 
         utilityManager.selectMailTemplateByKey(
           "NEW_ACCOUNT_TO_CLIENT"
         );       
       
       mailSender.setSubject(mailTemplate.getSubject());              
       
       mailSender.setContent(
         String.format(
           mailTemplate.getBody(),
           clientBean.getFirstName(),
           clientBean.getLastName(),
           clientBean.getLogin(),
           clientBean.getPassword(),           
           config.getProperty("HOST")
         )
       );       
                      
       mailSender.addRecipient(clientBean.getEmail1());                           
       mailSender.send();
       
       utilityManager.remove();
     } catch (Exception e) {
       handleException(e, "sendMail");       
     }
   }
   
   

   public String execute(
      ActionMapping actionMapping,
      HttpServletRequest request,
      HttpServletResponse response
   ) throws IOException, ServletException {
     try {       
       ClientBean clientBean = new ClientBean(); 
              
       clientBean.setId(idVal(request.getParameter("id")));
       
       clientBean.setOrganizationId(
         idVal(request.getParameter("organization_id"))
       );
       
       clientBean.setDepartmentId(
         idVal(request.getParameter("department_id"))
       );
       
       clientBean.setClientTypeId(
         idVal(request.getParameter("type_id"))
       );                         
       
       clientBean.setPosition(request.getParameter("pos"));
       clientBean.setAddress(request.getParameter("address"));
       clientBean.setNotes(request.getParameter("notes"));
       clientBean.setEmail1(request.getParameter("email1"));
       clientBean.setEmail2(request.getParameter("email2"));
       clientBean.setEmail3(request.getParameter("email3"));
       clientBean.setIcq(request.getParameter("icq"));
       clientBean.setTel1(request.getParameter("tel1"));
       clientBean.setTel2(request.getParameter("tel2"));
       clientBean.setTel3(request.getParameter("tel3"));
       clientBean.setFirstName(request.getParameter("firstName"));
       clientBean.setLastName(request.getParameter("lastName"));
       clientBean.setMiddleName(request.getParameter("middleName"));
       clientBean.setWww(request.getParameter("www"));
       clientBean.setLogin(request.getParameter("login"));
       
       //generate random password
       clientBean.setPassword(
          Utils.randomAlphanumeric(8)
       );       
       
       DateFormat dateformat = 
          DateFormat.getDateInstance(
             DateFormat.SHORT, 
             new Locale("ru")
          );

       try {
         clientBean.setBirthday(
           dateformat.parse(request.getParameter("birthday"))
         );
       } catch (Exception e) {
          //is not a date
       }
       
       
       ClientManagerLocalObject clientManager = 
          clientManagerHome.create();
       
       if(!isValid(clientBean, clientManager)) {
         OrganizationManagerLocalObject organizationManager =
           organizationManagerHome.create();
         
         Collection<ClientTypeBean> clientTypesList = 
           clientManager.selectClientTypes();         
         
         Collection<OrganizationBean> organizationsList = 
           organizationManager.selectOrganizations();
         
         //TODO replace to real id than id of FGI ARRIAH
         Collection<DepartmentBean> departmentsList = 
           organizationManager.selectDepartments(1);
                  
         organizationManager.remove();
         clientManager.remove();
         
         addErrorMessage(
            request, 
            config.getProperty("ERROR.CLIENTTFORM_FIELDS_INVALID")
         );
         
         request.setAttribute("clientBean", clientBean);
         request.setAttribute("departmentsList", departmentsList);
         request.setAttribute("organizationsList", organizationsList);
         request.setAttribute("clientTypesList", clientTypesList);
         request.setAttribute("error", clientFormErrorBean);      
         return actionMapping.getFailureTarget();
       }       
              
       if(clientBean.getId() == 0) {
         if(clientManager.addClient(clientBean)) {                  
           addInfMessage(request, config.getProperty("INF.CLIENT.ADDED"));
           if (request.getParameter("donotify") != null) {
             sendMail(clientBean);
           }
         }
       } else {         
         clientManager.updateClientByDispatcher(clientBean);         
         addInfMessage(request, config.getProperty("INF.CLIENT.UPDATED"));
         
         if (request.getParameter("donotify") != null) {
            String password = 
               clientManager.getUserPassword(clientBean.getId());
            clientBean.setPassword(password);
            sendMail(clientBean);
         }                 
       }
       
       clientManager.remove();
       
       /* Prepare to display clients list */
       ListClientsAction listClientsAction = 
         new ListClientsAction(clientManagerHome);
       listClientsAction.setConfig(config);
       
       return listClientsAction.execute(
          actionMapping, request, response
       );                     
    } catch (Exception e) {
       handleException(e, "execute");
       throw new InternalException("ErrorMessage.internal");
    }
   }
}